﻿using System;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;

namespace MimicAPI.DWM
{
    public class Thumbnail : IDisposable
    {
        Visual visual;
        IntPtr ThumbPtr;
        /// <summary>Zone where the thumbnail is kept</summary>
        HwndSource thumbZone;
        DWM_ThumbnailProperties properties;

        public Thumbnail(Visual visual, IntPtr source)
        {
            this.visual = visual;
            thumbZone = (HwndSource)HwndSource.FromVisual(visual);
            thumbZone.Handle.DwmRegisterThumbnail(source, out ThumbPtr);
            if (ThumbPtr == IntPtr.Zero)
                throw new Exception(string.Format("Creation failed for zone = '{0}' and source = '{1}'", thumbZone, source));
            properties = new DWM_ThumbnailProperties();
        }

        public Rect Destination
        {
            set
            {
                GeneralTransform transform = visual.TransformToAncestor(thumbZone.RootVisual);
                properties.Destination = (DWM_Rect)new Rect(transform.Transform(new Point(value.Left, value.Top)),
                                                            transform.Transform(new Point(value.Right, value.Bottom)));
                properties.Flags |= DWM_ThumbnailFlags.RectDestination;
            }
        }
        public Rect Source
        {
            set
            {
                properties.Source = (DWM_Rect)value;
                properties.Flags |= DWM_ThumbnailFlags.RectSource;
            }
        }
        public double Opacity
        {
            set
            {
                properties.Opacity = (byte)(255 * value);
                properties.Flags |= DWM_ThumbnailFlags.Opacity;
            }
        }
        public bool Visible
        {
            set
            {
                properties.Visible = value;
                properties.Flags |= DWM_ThumbnailFlags.Visible;
            }
        }
        public bool SourceClientAreaOnly
        {
            set
            {
                properties.SourceClientAreaOnly = value;
                properties.Flags |= DWM_ThumbnailFlags.SourceClientAreaOnly;
            }
        }

        public bool IsStillAlive { get { return (thumbZone.RootVisual != null) && thumbZone.RootVisual.IsAncestorOf(visual); } }

        bool isDisposed = false;
        /// <summary>IDisposable Members</summary>
        public void Dispose()
        {
            isDisposed = true;
            ThumbPtr.DwmUnregisterThumbnail();
        }

        ~Thumbnail()
        {
            if (!isDisposed)
                Dispose();
        }

        public int UpdateProperties()
        {
            return ThumbPtr.DwmUpdateThumbnailProperties(ref properties);
        }

        public Size GetSourceSize()
        {
            DWM_Size size;
            ThumbPtr.DwmQueryThumbnailSourceSize(out size);
            return size;
        }
    }
}
